Welcome.
In this lecture.
We're going to take a look at how to create a simple vehicle with suspension.
I've attached this model to the lecture, so you will want to go ahead and grab it so you can follow
along with me inside of this vehicle.
We have a couple of things.
We have a vehicle seat and inside of this vehicle seat we have some attachments.
So there's an attachment below the vehicle seat and there's an attachment above the vehicle seat.
And these are going to be for when our player exits the seat of the vehicle.
We're either going to teleport them to this top one or this bottom one, depending on if the car is
flipped or not.
And the vehicle has a proximity prompt in it as well.
So we can walk up to the car, activate the proximity prompt and drive the vehicle.
We have a model here and inside this is just for all of the tires and each tire has an attachment inside
of it.
And this attachment is just at the position that's in the directly in the center of our tire.
And then inside of our body we have an additional five attachments.
These attachments here are going to be for each of the tires because we're going to be connecting some
constraints of the attachments and the tires to these attachments here, which include a spring and
a cylindrical constraint, which we'll use in a little bit.
And then I have one more attachment here inside of the engine compartment.
And this just holds some audio, some sound instances that will play when the car starts up and when
it's driving.
We're just going to pick a random tire.
So I'm going to pick this tire right here.
And with this tire, we're going to create something called a cylindrical constraint right here.
And this constraint requires two attachments.
So the first attachment we're going to do is the one that corresponds to this front left tire, which
is the attachment for the front left tire right here.
And then the second attachment is going to be the one inside of our tire.
So we've created a constraint between this attachment and this attachment.
And what this constraint allows you to do is it allows this part to move in the direction that is defined
here, which I believe will be forwards and backwards.
So this constraint allows this tire to only move forwards and backwards an infinite amount of distance.
Of course, we're going to be using this cylindrical constraint to allow the tire to move only up and
down a bit to help with the suspension and to limit its movement.
So I'll just show you how this works real quick.
But before I do that, I'm going to anchor the body of the car so my car stays up in the air and we'll
hit play here.
And there is our cylindrical constraint.
As you can see, it has moved to the position that was in the attachment for our car.
But since we're going to be adding suspension later and the tire is going to be moving up and down,
it won't be teleported in a strange position.
But as you can see, if I touch the tire, you see it only moves forward and backwards infinitely in
these directions that are for the cylindrical constraint.
I can't move it this way.
I can't move it up or down.
It can only move forwards and backwards.
So in order to allow our tire to go up and down instead of forwards and backwards, what we'll need
to do is to rotate an attachment that is inside of the body.
So this attachment for our front tire here, we need to rotate this attachment by 90 degrees on the
Z axis, right?
So if we go to the orientation of the C frame, if we rotate it by 90 degrees, we should now allow
our tire to go up and down.
So if we go and play here.
You see now our tire has been rotated, but it only goes up and down now.
Now, the issue here is we need to rotate this tire itself to be vertical instead of horizontal like
this because a car's tires aren't horizontal.
Thankfully, that's also easy to do.
What we need to do is we need to go to the cylindrical constraint.
And inside of here there's an inclination angle property and we're just going to enter in 90 or representing
90 degrees.
And this should rotate the tire for us.
Now, if we play test here, you see now our tire.
Is vertical.
Now there's another issue.
Our tire is facing inwards.
We don't want it to face inwards because this is the inside part of the tire and that's the outside
part of the tire.
We want this part to be facing this way.
So again, what we could do is we can go to the attachment that is in the tire and we're going to rotate
it by 180 degrees.
So we're just going to flip it all around.
And again, we can do that on the Z axis.
We're just going to flip the tire entirely like that.
So as you can see, our attachment has been flipped.
And if we go and play, test it again.
As you can see, our tire is now facing in the proper direction.
Now, the next thing we need to do for our tire is we need to constrain its movements, because right
now it's going to go an infinite direction, upwards or downwards because there's no limit set on this
cylindrical constraint.
So in order to set a limit on our cylindrical constraint, there is a property in here and this property
is limits enabled.
So when I enable this property, you should see this bar appear and it's telling us what the limit is
going to be for our tire.
So we have a lower limit and an upper limit right now.
We don't want it to be at an upper limit of five.
So what I'm going to do is I'm going to set the lower limit.
I'm going to set this to -1.5, and that's -1.5 studs from this attachment.
And then the upper limit, I'm going to set to be -0.3.
So -0.3 studs from this attachment will be right here.
Now, the reason I'm doing this is because I don't want the tire to move above this attachment because
that means the attachment inside of the tire would go above this attachment.
And when that happens, well, we're going to be adding a spring.
Once this attachment goes above this attachment, the spring is going to flip around and the spring
is going to apply force this way.
But we only want the spring to apply force in this direction, right?
So we have to constrain how far up we can move the tire.
We don't want it to go above this attachment.
And here I've allowed the tire to go down a little bit more as well, just, you know, to have a tire
hang out when we're in the air.
Now, another thing I will note for the tires is I've enabled a property in here called Custom Physical
Properties.
And in here it allows me to change several things about this part.
It allows me to change the density or how much mass the part has.
It allows me to change the elasticity, which just kind of determines how much the part will bounce
around when it hits something.
It allows me to change the friction.
And of course we want to have a high friction.
I've increased the density of the tire to give it some more mass, and I've also increased the friction
and reduce the elasticity.
So if you ever wanted your car to drift more, then of course you'd want to reduce the friction that
I've set here.
But I've set it to 1.2 for all the tires.
Now the last thing we need to do for our tires, we need to create a spring attachment.
Or a spring constraint.
And inside of the spring constraint, again, two attachments.
We're going to first select the one that is in the car, which is going to be attachment for our front
tire and the left, and then the attachment that is inside of our tire.
And as you can see, it has created this spring constraint.
And like I was talking about earlier, we don't want this part to go above this part because that means
our spring right here is going to flip and it's going to be exerting force in the wrong direction.
We don't want to do that.
So in our spring constraint, we need to change some properties.
We see we have some right here.
We have one called dampening or damping.
And damping is used to kind of reduce or dampen and soften the force that is applied by the spring.
So typically a spring likes to go back to its resting state or its free length, which is one stud long.
So if I stretch the spring beyond one stud or I compress it below one stud, it's going to exert a force
to try to get back to that.
Free length and dampening allows us to soften that force out.
So instead of it being super springy, it's more gentle.
It kind of goes out slower.
So for this vehicle, I'm going to set the damping to be around 400.
Now for the free length, I want the spring to have a bit of room to stretch out.
So I would say the resting length of our spring should be probably around 2.5 studs, which you see
indicated by these blue arrows.
So our tire will push the car up a little bit.
Now for the stiffness.
This is going to be the amount of force that the spring is going to exert to try to get back to its
free length.
And these numbers are kind of arbitrary.
They're just kind of, you know, represent a higher number, more force.
But for this vehicle, a stiffness of around 5500 works pretty good.
Now, if we actually go and play test the game, you'll see the spring is going to stretch out to its
free length.
And as you can see, our tire is hanging here.
Now, if the car falls down and compresses on the spring, the spring is going to and exert a force
back to resist the gravity or weight of the car, which is going to push the car up.
If we had a stiffness that was too weak, then the spring would get compressed too much.
So that's why I thought 5500 was pretty good for this vehicle.
But of course you can go ahead and tweak it to however you like.
But now that we have all of this set up for this tire, there's one more thing we need to do.
And we need to stop this tire from colliding with the body.
Since this body is a mesh, the collision in the body is not exactly perfect.
So this tire is going to be colliding with the body when it tries to go up and down with the spring.
So an easy way to fix this would not to be using collision groups, but there's a constraint we can
use called no collision constraint, which allows you to select two parts for them not to collide with
each other.
So we can select the tire and we don't want the tire to collide with the body just like that.
Now that we've got the setup for this first hire, we need to do it for the rest of our tires.
So what I'm going to do is I'm going to copy all of these constraints and I'm going to paste it into
this one.
And what we're going to have to do is change the attachments in here.
So for this attachment, we need to do the front right tire and the attachment is going to be the one
inside of this tire.
For our no collusion constraint.
We need to select the front right tire and for the spring we need to do the same thing.
This is the front right tire attached to the attachment inside of the tire.
Now, we also need to make sure that we rotate the same thing here inside of this attachment.
So we did 180 degrees for this one.
We also need to do 180 degrees for this one as well.
And then we also need to rotate this attachment in here, which was by 90 degrees.
Again.
We'll do the same thing for the rear left tire.
We're going to select rear tire.
The attachment inside of the rear left tire for the collision again, rear left tire and then rear left
tire and the attachment inside of the tire.
Once more.
For this one, we'll just select for the rear right tire attachment in here.
Pick this tire and then again, the attachment for the rear.
And for this attachment.
Perfect.
So now we should have all of our tires set up.
And in order to make sure we confirm this is working, we can go and play a test real quick.
All right.
So you should be noticing a couple issues here.
These tires are looking a little wonky and we'll go ahead and have to fix that real quick.
Because we forgot to rotate these attachments.
So again, you have to rotate it by 180 degrees on these two attachments.
And then for the attachments and the tire.
Remember, we have to do 90 degrees.
Now if we play test again.
You should notice one more thing and you will see that these tires here are rotated correctly, but
these tires are not.
And that's because I had to copy and paste one of these tires and use them for the rest, which means
I had to rotate one of them.
So they're being flipped in the wrong direction.
And an easy way to fix that would to be to just select these two tires.
And for the attachments in them.
We just need to undo that 180 degree rotation that flipped them around.
So one more time if we play test.
You will see that all of our tires are facing the correct direction.
And that also means if I go to an anchor, the body of the car just like so.
You will now see that our tires are holding up the car.
But it's been a little weird.
I think there's some problems with the physics because I'm recording and it's trying to calculate physics
at the same time, but I think it's figured itself out.
But as you can see now, we have suspension on our vehicle.
And if I jump on the vehicle, you can see the suspension working there.
So I'm hopping on my vehicle and you can see our car has some nice suspension.
Now we need to do another thing inside of all of our cylindrical constraints.
I'm going to select all of them.
We have to change something in here called angular actuator type.
And this is going to allow us to rotate the tires and allow the car to drive.
So that means we need to set this actuator type to motor.
And when you do this, you should see all of these blue arrows show up and it's telling us the direction
that the tires will rotate when we apply a positive force on the tire.
So and here we get a few more properties, we get an angular velocity.
The velocity of the rotation of our tire and then the torque for the motor that's rotating our tire.
Of course we're going to need some torque.
If we don't, it's going to take forever to rotate the tires.
So as an example, I'm going to set this to 4000 and I'm just going to run the server.
And inside of our tires.
What I'll do for each of these cylindrical constraints.
Is that I'm going to apply some force here.
So I'm going to increase the angular velocity to ten.
And as you can see, all of the tires on our car start rotating.
But if I reduce the torque to something, let's say ten.
And then I set the angular velocity to zero.
You'll see that the tires take a long time to stop because we have very little torque.
But now that they've stopped, if I keep the torque low actually at like ten and then I try to apply
some velocity that's hires like 100.
You see, it takes a very long time for them to go.
And that's because we don't have much talk here.
But if I set the talk to something like 5000, we're able to speed up these tires a lot faster, basically
instantly, because we have more torque.
And in order to have our vehicle drive around and pull itself up mountains, we need more torque.
So for this vehicle in particular, I found that a torque of around 7000 should work just fine.
So I'm going to stop the test and I'm going to reset these talks back to zero, because now is the time
we can start scripting our car.
What I'm going to do is I'm going to create a new script inside of the vehicle seat.
We can just name this script, something like vehicle script and the script.
We're going to need a few things.
We're going to need some services.
So we'll just need between service in this case.
And then we'll need some variables.
One, we need to store the car, which is easy.
It's just going to be script dot parent, dot parent.
Actually, you know what?
I'll just put the script directly in the car instead.
So that way it's just script dot parent.
We'll just do that instead.
Next, we need to reference the model for the tires.
So that'll just be car tires.
And then since we want the car to drive, we're going to need to reference all of the cylindrical constraints
inside of each tire so we can apply a velocity in here to get the car moving.
So we'll just reference each one.
We'll do cyl cylindrical.
And we'll do front left equal to tires.
Dot front l dot cylindrical constraint.
Do the same thing for the front, right?
We'll do one for the rear as well.
So we'll do rear left equal two tires.
Rear left.
Cylindrical constraint and then cylindrical.
Oops.
There we go.
Cylindrical rear right.
Equal tires dot rear dot, cylindrical constraint.
Then I'll create a reference to the seat in the car, which is just car dot.
Vehicle seat.
I'll create a reference to the prompt in the seat that's equal to seat dot proximity prompt.
And then I'm going to keep track of who is currently sitting in the seat.
We'll just call it current occupant.
Set it to nil.
And then we'll need to reference the sounds that are in the vehicle.
So we'll do one for the idle sound.
It's going to be in the car.
We get the body of the car and there's an attachment in there called engine sounds and we'll get the
car idle sound and then we'll have the start sound as well.
Okay.
And then we'll need some constants.
And these constants are going to define some limitations on our vehicle.
So the first limitation we need to define is the max angular velocity.
So what's the max velocity that we want to apply for the tires?
And we can do this by checking to see what the max speed property is here in our seat.
And inside I've set the max speed to be 65 or 65, I believe Studs.
I think it's 65 studs per second, if I'm correct.
And I also set the torque that we'll use for the vehicle as well.
But in order to calculate the max angular velocity, we need to get the seats dot max speed.
And we need to divide it by the radius of one of the tires so that way we can get the max angular velocity.
So it's easy to get one of the radius of the tires.
We just need to grab one.
We'll just do tires, Dot.
Let's just do front left.
We'll get the size of it in the y axis and that's going to be the total width of our tire.
But we want the radius, which is half of the total width.
So we'll just divide it by two and we'll get our max angular velocity to make sure that we don't go
above this max speed.
Next, we need to set a constant for defining.
How far we want the tires on the front to rotate when we're steering.
So the max rotation will have is 35 degrees, so the tires will rotate 35 degrees to the left or to
the right to turn either left or right.
And then we needed to define a constant for our ideal sound.
So my plan is, is that when we're driving the car, when the car goes faster and faster, we're going
to set the playback speed of our car idle sound to be higher and higher, which makes it sound like,
you know, the car is driving faster and faster.
It's having higher RPM.
But when the car is not moving, we still want the idle sound to be playing, which is why we need a
minimum playback sound for when we're idling.
And that's going to be a playback speed of, let's say, 0.6.
One more constant is going to be called rotation duration.
What is this for?
So when we turn the steering wheel to go left or right, how long do we want it to take for the tires
to rotate either left or right?
And I found that about 0.4 seconds would be good for that.
Next thing we need to do is define one function.
And this function is going to be for updating the playback speed of our idle sound.
I'll just call it update audio.
And then we'll need to listen to some events.
Well, first off, we need to listen to when our prompt gets triggered because a player wants to enter
the vehicle.
We need to listen to when a property in the seat changes.
That's called occupant.
So the vehicle seat has a property in here that tells us who the occupant of our seat is.
Where is that at?
Here it is right here.
Occupant So whenever a player goes into the seat, it'll tell us the humanoid of that player so we can
get the occupant.
So we'll get property change signal.
That's going to be occupant.
And when that property changes, we are going to do some stuff in there.
We also need to listen to when a property in the seat called steer changes.
So get property change signal steer.
And what this does is that if we turn left, the steer property turns to the number one.
If we steer to the right, it turns to negative one.
And if we don't steer at all, it's zero.
So we need to pay attention to that.
And we also need to pay attention to when the player presses on the gas to either go backwards or forwards
so we can do seat jet property change signal.
And this property is called throttle.
So if we go forwards, it's a positive number of one.
If we go backwards, it's negative one.
If we don't move at all, it's zero.
So we'll connect a function to that as well.
And that's all we need to do.
So what we can first fill out is the event for when our prompt gets triggered by a player.
So what we want to do is we first want to check is if there's already someone sitting in our vehicle.
So if our seat already has an occupant, then we'll just return, right?
You can't have two drivers of a car.
The next thing we want to check for is if the player who activated this prompt has a character model.
Because if they don't, well, we don't want to put them in the seat.
And exploiters can also fire prompts, even if they don't have a character or anything, they can just
fire them whenever they want.
So we got to make sure we stop that.
So if this player doesn't have a character, so if not player dot character, then we'll just return
as well.
Otherwise we can use a function on our C and it's called sit.
And what we do is we pass a humanoid to this function and it forces them to sit in the car seat.
In this case, that's going to be the player's character humanoid.
So now we are forcing the player to sit in the seat and that's all we need to do there.
But next, we need to listen for when that occupant property gets updated.
Because when we force the player to sit, then it's going to update this property.
So what do we want to do?
Well, we want to listen If the seat gets an occupant so we get a new occupant, then what we want to
do is we want to set that variable of current occupant to the seat dot occupant.
We want to disable the prompt so nobody else can enter the vehicle.
And when the player enters the vehicle, we want to play the ignition sound.
So the car is starting up.
So we'll play that sound.
And I don't want the car to idle right away because we have to get past that ignition.
So I'll just wait like two seconds, because if we go to our sound here, that is inside of our body.
We have to wait about two seconds before the car starts idling.
So we'll wait for that.
And then once those two seconds are up, then we can start playing the Idol sound, which is set to
loop forever until we stop the sound.
However, after we wait for these two seconds, there could be a chance that the player sits down and
then immediately sits back up.
And we don't want to play the idol sound if there's no occupant.
So after we wait for two seconds, we still need to make sure there is a seat occupant if there isn't.
Then we'll just return.
We don't need to play the sound.
So we'll do idle play.
And then once we start playing the idling sound, that's when we need to start updating the audio for
our idling sound.
So that's why we'll call this function here.
So what's this function going to do?
Well, this function is going to loop for us.
So while we have an occupant.
So while seat occupant is true.
Then what we're going to do is we're going to set the playback speed of our idle sound equal to this.
We're going to call the math.max function and we're going to pass minimum playback speed.
Actually.
Why did I name it sound?
Should be Speed.
Minimum.
Playback.
Speed.
So minimum playback speed.
In case the second number we pass goes below the minimum playback speed.
We're guaranteed to have a playback speed of at least 0.6 because if it goes to like 0.1 or 0 or negative
or whatever, this gets the maximum number and this will always be the max if the second number goes
below it.
So what is the second number going to be?
Well, it's going to be the minimum playback speed, but we're going to multiply it by this.
We're going to multiply it by the cars primary part, which is the body of the car inside of the model.
I set the primary part to be the body and this body, since it has all of this stuff attached to it.
It's called an assembly.
And this assembly has a velocity.
So when it's moving, the game is like, hey, this has this has a velocity in a specific direction.
And from that we can calculate how fast the car is moving.
So we can get the assembly linear velocity and we can get the magnitude of this velocity.
So it just returns to us a number that represents how far out this velocity is.
How big is this vector?
Because if we're only moving at like one stud per second, then this vector is going to be super tiny.
Our magnitude is going to be small, but if we're moving at like 50 studs per second, then it's going
to be a larger magnitude, which means we're going faster.
And that means we have to increase the playback speed of our idling sound.
But let's say we're we are moving 55 studs per second.
That's going to return a value of like 55 here.
And if we multiply 55 by our 0.6, we're going to get a playback speed of like 20 something, which
is way too fast.
So we need to reduce this number down a lot, but by not too much.
And if we divide it by 20, that should give us a pretty good number for our playback speed.
Of course you can mess with this magic number to, you know, adjust how how fast you want the playback
speed of our audio to be while we're driving.
But I found 20 to be pretty good.
And of course, since we're in a while loop, we need to yield and we'll yield 4.05 seconds.
So this will update the playback speed of our sound every 0.5 or 0.0 five seconds.
Anyway.
So once we've got all that done and there's a player in the seat, whenever they, you know, press
A or D on their key, it's going to update this steer property.
And that means we want to steer the front tires In order to steer the front tires, we need to rotate
those attachments.
That's in the tire because it's using that cylindrical constraint.
If I rotate the attachment in the tire, then it'll rotate the tire itself.
So we need to calculate an orientation and it's going to be a new vector three.
We don't need to rotate it on the x axis, but we need to rotate it on the vertical y axis and we're
going to rotate it by.
We're going to get the seat dot steer, which is either going to be negative one, 1 or 0, and we're
going to multiply it by the max tire rotation.
So if we're not steering, it's zero, then we're not going to rotate the tire at all.
If it's negative one, we multiply this and rotate it in the other direction, but it's actually going
to rotate in the opposite direction.
So if we press A, it's going to rotate to the right.
And if we press D on our keyboard, it's going to rotate to the left.
So I'm going to make sure to negate the posterior value.
And then for the Z is very important.
Remember that the attachments that are inside of our tires are actually excuse me, we're rotating,
not the attachment on our tires, but we're actually rotating the attachment in the body.
Let me just correct that real quick.
We're rotating these attachments to rotate our tires and not the ones in here.
And we need to remember that each of these attachments, we've already rotated them by 90 degrees on
the Z axis.
So we've got to make sure we include that.
We don't want that to change.
But since we've applied this orientation, that means we can rotate the tires.
But I don't want to rotate the tires instantly and said I want them to slowly move to that position
based on this rotation duration.
And that's where the tween service comes in.
So we're going to create two new tweens.
We're going to do tween service and we're going to create a tween on what we're going to get the body
and we're going to get the front attachment for one of the tires.
So first we'll do front attachment for the left tire.
We're going to create a new tween info.
And inside there, we're just going to have the rotation duration and what do we want to tween We want
to tween the orientation of our attachment, which is going to be equal to the orientation that we just
created right here.
And of course, since this create function in our tween service going to return to us a track, we can
play it right here.
We can just call play and we don't need to store the return from this function in a variable.
And then we can just copy this.
And do the exact same thing, but for the front right tyre.
Just like that.
So what we can do is we can test what we've got done so far.
And if I go and play here.
You see if I hop in my vehicle.
We get the start ignition sound and then we get the idling sound.
And if I press A on my keyboard, the tires tween to the left, if I let go of a they tween to be neutral,
and if I press de they tween to the right.
So very cool.
Inside of this function here.
We need to listen for when we press down on the throttle.
So the very first thing we need to do is we need to set the torque in all of our cylindrical constraints
to the torque that has been defined in our vehicle seat.
And that's going to be easy.
We just need to create a reference to that value.
Equal to stalk.
And then for every single one of these cylindrical constraints that we've referenced up here, we just
need to set the torque to that.
So.
Cylindrical.
Right.
Left stalk.
Or I believe it is motor max torque.
We're just setting it to talk.
Do it again for the.
Rear.
Right.
Do it again.
It looks like I misspelled that one.
So.
Rent, cylindrical, cylindrical.
There we go.
We'll fix that right here.
And then we need to do this for the front.
So we'll do front right motor max torque equal to torque.
And then we need to do the last one for the front left.
Now that we've set the torque, that means we can start to rotate our tires.
And that means we need to calculate the correct angular velocity for the tires.
How do we do that?
It's going to be pretty simple.
We can just create a variable, call it angular velocity.
And we're going to set it equal to the seats throttle, which is either going to be negative one, 0
or 1.
And we just multiply it by our max angular velocity.
So if we want to go forward, it's going to be one times the max angular velocity.
If we're going backwards, this number will be negative and that means the tires are going to rotate
the other way.
So we go backwards.
And if it's zero, then we have no angular velocity at all.
Pretty easy.
So then we can just copy this.
And we're going to set it to this angular velocity.
Copy that.
And just paste them all here.
And we need to set that in the.
And your velocity property.
Just copy that and paste it there, paste it there and paste it there.
Very cool.
So now if we go and play again.
If I press a W, our tires should start rotating forwards.
There we go.
They're rotating forwards.
I let go of w they stopped.
If I press s, they rotate backwards and I release s and we're all good to go.
Very cool.
So the next thing we need to do is when the player jumps up out of the seat, we need to either put
them at the position of this exit attachment at the bottom of the car or the top of the car, because
if the car is flipped over, we need to set their position to be on this bottom attachment.
Well, we can go back to this property here.
And we're going to listen.
So when this occupant property changes and there is no occupant, meaning the last player who was ever
in the vehicle jumped out of the seat.
What we need to do is we need to check if there was a current occupant that was last sitting in the
car, if there was.
Then we need to figure out which attachment we need to teleport their torso to.
So I'll just create a variable called exit attachment.
And then what we could do is we can check if the seat dot attachment exit top, we're going to get the
world keyframe the position of that attachment in the world.
And get its y axis.
And we're going to check if this y axis is above the other attachment.
So attachment exit bottom world C frame dot position dot y.
So if this attachment is above our bottom attachment, meaning our car isn't flipped over.
Then our exit attachment is just going to be equal to that attachment exit top.
Otherwise, if it's below, then we need to set the exit attachment equal to seat dot exit attachment
at the bottom.
So attachment exit bottom.
Once we do that, we can get the current occupant and we get the parent.
Because remember, current occupant represents a humanoid and the parent of the humanoid is the player's
character.
And then we get the humanoid root part and the player's character, and we set the position equal to
the exit attachment that world keyframe and get that position.
And then once that's done, we just set current occupant to nil because there is no more occupant.
They got out.
We also need to reset the prompt to be enabled again because there's no one in the car anymore.
So prompt dot enabled equals true.
And then we need to stop the start sound and the idle sound in case they were playing.
So start sound.
We're going to stop an idle sound.
We're going to stop just like that.
And I think that's it for the car.
So let's just go ahead and play test here just to make sure everything works as we expect and then we
can go drive it around a little bit.
So the car starts up idle sound.
We can turn the tires in the correct direction.
We can spin the tires forward backwards.
And if we hop out, you see, we get teleported to that attachment above the car.
However, let's say I decided to make the car upside down.
And we'll playtest it again.
Because this top attachments y position is going to be less than the one that is underneath the car.
If I exit the car, we get teleported to the attachment below the car.
Very cool.
Let's rotate our car back to normality.
We're going to anchor the body.
And I've actually generated some terrain over here because we're going to test this bad boy out.
So we're going to put our car right there.
We're going to play right here.
Now we're going to see if our car works as we expect.
Of course, the physics are going to be a little weird because my processor is being taken up by the
recording software and trying to calculate physics at the same time.
So it might be a little wonky, but if we get in, our car starts up good and we should be able to start
driving.
But as you can see, we can rotate our tires and now we can drive.
And as you can see, when our speed goes up, the idle sound gets its playback speed increased.
Right.
Just like that.
And as you can see, our suspension is helping us out, making this ride a lot smoother.
As you can see, our tires are moving up and down independently because of the spring we put in there.
And those springs are also helped out by those cylindrical constraints that forces the tires to move
only up and down a set amount so that the tires can only move up so much and they can only move down
so much, just like it would be in an actual car.
And since I have also increased the friction on the tires, we aren't sliding around that much at all.
Now, if I were to go into the properties for these tires, these custom physical properties we set
and let's say I reduce the friction to like 0.1.
What do you think's going to happen?
I say we're going to drift around all over the place.
Let's find out.
I don't think we're actually going to be able to grip the ground at all.
Well.
But if I drive around.
Yeah.
You can see we are drifting around.
Watch more.
Even though I stopped the car.
You see, we are drifting around a lot more than before.
But I'm going to, of course, reset that friction to be higher again.
1.22.
Maybe.
Maybe we'll try out 1.5.
Maybe that's a little better.
As you can see, we don't drift around as much anymore.
I mean, we pretty much stop, which is what a tire is supposed to do.
It's made out of rubber.
It would make sense.
But otherwise, that's how you make a car with suspension or a simple car in Roblox.
As you can see, it's actually not that complicated.
You just need to have a little bit of knowledge on a couple of constraints inside of the Roblox API.
Of course, you need to understand a little bit about angular velocity and torque on cars, but other
than that, it only took us 89 lines of code and we've got a working car here that can turn, go forwards,
go backwards, and if it flips upside down like this, we can hop out of the car and make it out.
So I hope you enjoyed this lecture and I'll see you in the next one.